/*
 * Copyright (c) 2016 JUI All rights reserved.
 */

;(function () {

    /**
     * 验证
     * <pre>
&lt;form id=&quot;ff&quot;&gt;
    验证结果:
   &lt;span id=&quot;result&quot;&gt;&lt;/span&gt; 
   &lt;br /&gt; 
   &lt;table&gt; 
    &lt;tbody&gt;
     &lt;tr&gt; 
      &lt;td&gt;验证正整数:&lt;/td&gt; 
      &lt;td id=&quot;t1&quot;&gt; &lt;input msgid=&quot;msgId1&quot; name=&quot;name1&quot; rules=&quot;[{rule:{positiveInt:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;X 请输入整整数&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId1&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证自然数(长度4~10):&lt;/td&gt; 
      &lt;td id=&quot;t2&quot;&gt; &lt;input msgid=&quot;msgId2&quot; name=&quot;name2&quot; rules=&quot;[{rule:{naturalNum:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入自然数&#x27;}
			,{rule:{minLength:4,maxLength:10},successMsg:&#x27;√&#x27;,errorMsg:&#x27;长度必须为4~10&#x27;}
			]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId2&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证正数:&lt;/td&gt; 
      &lt;td id=&quot;t3&quot;&gt; &lt;input msgid=&quot;msgId3&quot; name=&quot;name3&quot; rules=&quot;[{rule:{positiveNum:true,notNull:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入大于零的数&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId3&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证浮点数:&lt;/td&gt; 
      &lt;td id=&quot;t4&quot;&gt; &lt;input msgid=&quot;msgId4&quot; rules=&quot;[{rule:{floatNum:true,notNull:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入浮点数&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId4&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证正浮点数:&lt;/td&gt; 
      &lt;td id=&quot;t5&quot;&gt; &lt;input msgid=&quot;msgId5&quot; rules=&quot;[{rule:{positiveFloatNum:true,notNull:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入正浮点数&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId5&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证非负浮点数:&lt;/td&gt; 
      &lt;td id=&quot;t6&quot;&gt; &lt;input msgid=&quot;msgId6&quot; rules=&quot;[{rule:{notNegativeFloatNum:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入非负浮点数&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId6&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证邮箱:&lt;/td&gt; 
      &lt;td id=&quot;t7&quot;&gt; &lt;input msgid=&quot;msgId7&quot; rules=&quot;[{rule:{email:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入正确的邮箱&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId7&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证手机号:&lt;/td&gt; 
      &lt;td id=&quot;t8&quot;&gt; &lt;input msgid=&quot;msgId8&quot; rules=&quot;[{rule:{mobile:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入正确的手机号&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId8&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;验证电话:&lt;/td&gt; 
      &lt;td id=&quot;t9&quot;&gt; &lt;input msgid=&quot;msgId9&quot; rules=&quot;[{rule:{tel:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入正确的电话号&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId9&quot;&gt;&lt;/td&gt; 
     &lt;/tr&gt; 
     &lt;tr&gt; 
      &lt;td&gt;passValidate=&amp;quot;true&amp;quot;属性:&lt;/td&gt; 
      &lt;td id=&quot;t9&quot;&gt; &lt;input msgid=&quot;msgId9&quot; passvalidate=&quot;true&quot; rules=&quot;[{rule:{tel:true},successMsg:&#x27;√&#x27;,errorMsg:&#x27;请输入正确的电话号&#x27;}]&quot; /&gt; &lt;/td&gt; 
      &lt;td id=&quot;msgId9&quot;&gt;passValidate=&amp;quot;true&amp;quot;可以跳过验证&lt;/td&gt; 
     &lt;/tr&gt; 
    &lt;/tbody&gt;
   &lt;/table&gt; 
  &lt;/form&gt; 
     * </pre>
     * @class JUI.Validate
     * @extends JUI
     */
    JUI.Class('Validate', {
        OPTS: $.extend({
            rule: {}
            , msgId: ''
            , errorMsg: ''
            , successMsg: ''
            // 自定义校验方法
            , validateHandler: null
        }, JUIConfig.Validate)

        /**
         * 构造函数
         * @private
         */
        , init: function (opts) {
            this.opts = $.extend({}, this.OPTS, opts);
            this.setMsgId(this.opts.msgId);
        }
        /**
         * 设置提示信息的id
         */
        , setMsgId: function (id) {
            this.opts.msgId = id;
            this.$msgDiv = $('#' + this.opts.msgId);
        }
        , showErrorMsg: function (msg) {
            if (this.opts.errorClass) {
                this.$msgDiv.removeClass().addClass(this.opts.errorClass);
            }
            this.$msgDiv.html(msg || this.opts.errorMsg);
        }
        , showSuccessMsg: function (msg) {
            if (this.opts.successClass) {
                this.$msgDiv.removeClass().addClass(this.opts.successClass);
            }
            this.$msgDiv.html(msg || this.opts.successMsg);
        }
        /**
         * 验证操作
         */
        , validate: function (val) {
            if (typeof this.opts.validateHandler === 'function') {
                var succ = this.opts.validateHandler(val);
                if (!succ) {
                    this.showErrorMsg();
                }
                return succ;
            }
            var rule = this.opts.rule;
            for (var key in rule) {
                // 检测空值
                var len = this.getValueLength(val);
                if (len === 0) {
                    if (this.opts.rule.notNull) {
                        this.showErrorMsg();
                        return false;
                    }
                    return true;
                }

                // 检测长度
                if (!this.validateLength(val)) {
                    return false;
                }

                var shouldValidate = rule[key];
                if (shouldValidate && !this.validateItem(val, key)) {
                    return false;
                }
            }
            // 验证成功
            this.showSuccessMsg();
            return true;
        }
        /**
         * 验证长度
         */
        , validateLength: function (val) {
            var len = this.getValueLength(val);
            var mixLen = this.opts.rule.minLength || -1;
            var maxLen = this.opts.rule.maxLength || -1;
            if (mixLen !== -1) {
                if (len < mixLen) {
                    this.showErrorMsg();
                    return false;
                }
            }

            if (maxLen !== -1) {
                if (len > maxLen) {
                    this.showErrorMsg();
                    return false;
                }
            }

            return true;
        }
        /**
         * 验证单个项
         */
        , validateItem: function (val, item) {
            var validateMap = JUI.ValidateStore;
            var validateHandler = validateMap[item];
            if ($.isFunction(validateHandler)) {
                // 验证不通过
                if (!validateHandler(val)) {
                    this.showErrorMsg();
                    return false;
                }
            }
            return true;
        }
        /**
         * 返回字节长度,一个汉字返回2个长度
         */
        , getValueLength: function (value) {
            if (typeof value === 'undefined') {
                return 0;
            }
            // 如果是数组
            if ($.isArray(value)) {
                return value.length;
            }
            return (value + '').replace(/[^\x00-\xff]/g, "**").length;
        }
    });

    /**
     * @ignore
     */
    JUI.ValidateStore = (function () {
        var reg_positiveInt = /^[1-9]\d*$/
            , reg_naturalNum = /^(0|([1-9]\d*))$/
            , reg_positiveNum = /^(((0|([1-9]\d*))[\.]?[0-9]+)|[1-9])$/
            , reg_floatNum = /^-?[0-9]{1,4}([.]{1}[0-9]{1,})?$/
            , reg_positiveFloatNum = /^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/
            , reg_notNegativeFloatNum = /^[0-9]{1,4}([.]{1}[0-9]{1,})?$/
            , reg_email = /^\s*[_a-zA-Z0-9\-]+(\.[_a-zA-Z0-9\-]*)*@[a-zA-Z0-9\-]+([\.][a-zA-Z0-9\-]+)+\s*$/
            , reg_mobile = /^\s*(\+86)*0*1(3|5|8)\d{9}\s*$/
            , reg_tel = /\(?0\d{2,3}[)-]?\d{7,8}/

        return {
            /**
             * 匹配正整数
             */
            positiveInt: function (val) {
                return reg_positiveInt.test(val);
            }
            /**
             * 匹配自然数,0,1,2,3...
             */
            , naturalNum: function (val) {
                return reg_naturalNum.test(val);
            }
            /**
             * 匹配正数
             */
            , positiveNum: function (val) {
                return reg_positiveNum.test(val);
            }
            /**
             * 匹配浮点数
             */
            , floatNum: function (val) {
                return reg_floatNum.test(val);
            }
            /**
             * 匹配正浮点数
             */
            , positiveFloatNum: function (val) {
                return reg_positiveFloatNum.test(val);
            }
            /**
             * 匹配非负浮点数（正浮点数 + 0）
             */
            , notNegativeFloatNum: function (val) {
                if (val === 0) {
                    return true;
                }
                return reg_notNegativeFloatNum.test(val);
            }
            /**
             * 匹配邮箱
             */
            , email: function (val) {
                return reg_email.test(val);
            }
            /**
             * 匹配手机号
             */
            , mobile: function (val) {
                return reg_mobile.test(val);
            }
            /**
             * 匹配联系电话
             * (010)88886666，或022-22334455，或02912345678
             */
            , tel: function (val) {
                return reg_tel.test(val);
            }
        };
    })();

})();